using AutoMapper;
using BackData;
using Domain;
using Domain.BOM;
using Domain.DTOs.BOMs;
using Infratructure;
using MediatR;
using System.Transactions;
using Team.API.Applocation.Command.BOM;
using Yitter.IdGenerator;

namespace Team.API.Applocation.Hanldler.BOM
{
    /// <summary>
    /// 创建成品BOM处理器
    /// </summary>
    public class CreateProductBOMHandler : IRequestHandler<CreateProductBOMCommand, APIResult<BOMDTO>>
    {
        private readonly IRepository<Bomtable> bomRepository;
        private readonly IRepository<Nlogmodel> nlogRepository;
        private readonly IMapper mapper;
        private readonly ILogger<CreateProductBOMHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="bomRepository">BOM仓储</param>
        /// <param name="nlogRepository">日志仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public CreateProductBOMHandler(
            IRepository<Bomtable> bomRepository,
            IRepository<Nlogmodel> nlogRepository,
            IMapper mapper,
            ILogger<CreateProductBOMHandler> logger)
        {
            this.bomRepository = bomRepository;
            this.nlogRepository = nlogRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 处理创建成品BOM请求
        /// 使用事务同时操作BOM表和日志表，确保树形业务正常使用
        /// </summary>
        /// <param name="request">创建命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作结果</returns>
        public async Task<APIResult<BOMDTO>> Handle(CreateProductBOMCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<BOMDTO>();
            // 获取当前登录人，如果为空则使用"系统"作为默认值
            var currentUserName = string.IsNullOrWhiteSpace(request.CurrentUserName) ? "系统" : request.CurrentUserName;

            // 记录接收到的用户名参数，用于调试
            logger.LogInformation($"[创建成品BOM] 接收到的CurrentUserName参数：{request.CurrentUserName ?? "null"}，最终使用的操作人：{currentUserName}");

            try
            {
                logger.LogInformation($"[创建成品BOM] 开始执行，操作人：{currentUserName}，成品名称：{request.Goodsname}，成品编码：{request.Itemcode}");

                // 检查成品编码是否已存在（同一编码的成品不能重复）
                var existsByItemcode = bomRepository.GetAll()
                    .Any(x => x.Itemcode == request.Itemcode && x.Category == "成品" && x.IsDel == false);
                if (existsByItemcode)
                {
                    logger.LogWarning($"[创建成品BOM] 成品编码 {request.Itemcode} 已存在，操作人：{currentUserName}");
                    result.Code = StateCode.Fail;
                    result.Message = $"成品编码 {request.Itemcode} 已存在，请使用其他编码。";
                    return result;
                }

                // 生成子级ID（用于树形结构）
                var childId = GenerateChildId();

                // 创建成品BOM实体
                var entity = new Bomtable
                {
                    Id = YitIdHelper.NextId(),
                    Itemcode = request.Itemcode,
                    Goodsname = request.Goodsname,
                    Spec = request.Spec ?? string.Empty,
                    Unit = request.Unit ?? string.Empty,
                    Category = "成品", // 成品BOM固定分类为"成品"
                    Version = request.Version ?? "1.0V",
                    Number = request.Number,
                    Remark = request.Remark ?? string.Empty,
                    IsUse = request.IsUse,
                    Parentid = "F0", // 成品BOM的父级ID固定为"F0"（根节点）
                    ChildrenId = childId, // 生成子级ID用于树形结构
                    IsDel = false
                };

                // 创建操作日志实体
                var logEntity = new Nlogmodel
                {
                    Id = YitIdHelper.NextId(),
                    Message = $"{currentUserName}创建成品BOM成功，成品名称：{request.Goodsname}，成品编码：{request.Itemcode}，版本：{request.Version}",
                    Category = "BOM",
                    Otherkey = entity.Id,
                    Operatingtime = DateTime.Now,
                    Operator = currentUserName,
                    IsDel = false
                };

                // 使用事务确保BOM表和日志表同时操作成功
                using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 添加BOM记录
                        var bomRows = await bomRepository.AddAsync(entity);
                        if (bomRows <= 0)
                        {
                            logger.LogError($"[创建成品BOM] BOM表插入失败，操作人：{currentUserName}，成品名称：{request.Goodsname}");
                            result.Code = StateCode.Fail;
                            result.Message = "成品BOM创建失败：数据插入失败";
                            return result;
                        }

                        // 添加操作日志
                        var logRows = await nlogRepository.AddAsync(logEntity);
                        if (logRows <= 0)
                        {
                            logger.LogError($"[创建成品BOM] 日志表插入失败，操作人：{currentUserName}，BOM ID：{entity.Id}");
                            result.Code = StateCode.Fail;
                            result.Message = "成品BOM创建失败：日志记录失败";
                            return result;
                        }

                        // 提交事务
                        transaction.Complete();

                        logger.LogInformation($"[创建成品BOM] 创建成功，操作人：{currentUserName}，BOM ID：{entity.Id}，成品编码：{request.Itemcode}，子级ID：{childId}");

                        result.Code = StateCode.OK;
                        result.Message = "成品BOM创建成功";
                        result.Result = mapper.Map<BOMDTO>(entity);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"[创建成品BOM] 事务执行失败，操作人：{currentUserName}，成品名称：{request.Goodsname}，错误信息：{ex.Message}");
                        result.Code = StateCode.Fail;
                        result.Message = $"成品BOM创建失败：{ex.Message}";
                        throw; // 抛出异常以触发事务回滚
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"[创建成品BOM] 处理失败，操作人：{currentUserName}，成品名称：{request.Goodsname}，错误信息：{ex.Message}");
                result.Code = StateCode.Fail;
                result.Message = $"成品BOM创建失败：{ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// 生成子级ID（用于树形结构）
        /// </summary>
        /// <returns>子级ID</returns>
        private string GenerateChildId()
        {
            var totalCount = bomRepository.GetAll().Count();
            var suffix = totalCount;
            string childId;
            do
            {
                suffix++;
                childId = $"F{suffix}";
            } while (bomRepository.GetAll().Any(x => x.ChildrenId == childId && x.IsDel == false));

            return childId;
        }
    }
}

